<!-- 登录组件 -->
<script setup lang="ts">
import {Server} from "@/stores/ajax";
import {reactive, ref, h, watch, nextTick} from "vue";
import {Lock, Avatar} from "@element-plus/icons-vue";
import type {FormInstance, FormRules} from "element-plus";
// import 'element-plus/es/components/message/style/css'
// import 'element-plus/es/components/notification/style/css'
// import {ElMessage, ElNotification} from 'element-plus'
import {GetUserState} from "@/stores/userState";
import {useRouter, useRoute} from 'vue-router'
import {RefType} from "vue/macros";
let user = GetUserState();
let router = useRouter()

let loginData = $ref({
    username: localStorage.getItem("username") ?? "",
    password: localStorage.getItem("password") ?? "",
});
let rememberPassword = $ref(Boolean(Number
    (localStorage.getItem("rememberPassword"))) ?? false)

const formSize = $ref("default");
const registerFormRef = $ref<FormInstance>();
const registerData = reactive({
    username: "",
    password: "",
    email: "",
    vc: ""
});
const sentVCTime = ref(0)
const sentVCTimeTick = (setTime = 0) => {
    if (setTime > 0) {
        sentVCTime.value = setTime
    }
    if (sentVCTime.value <= 0) sendVCCTimer = null
    else
        sendVCCTimer = setInterval(() => {
            if (sentVCTime.value <= 0) sendVCCTimer = null
            else
                sentVCTime.value -= 1
            sentVCTimeTick()
        }, 1000)
}

const checkUsername = (rule: any, value: any, callback: any) => {
    if (value.length >= 3) {
        return Server.get("/user/user_exists", {username: value}, false).then((res) => {
            if (res.data && res.data.code != 0) {
                callback()
            } else {
                callback(new Error("用户名已存在！"))
            }
        });
    }
}
const checkEmailExists = async (email: any) => {
    return Server.get("/user/user_exists", {email}, false).then((res) => {
        if (res.data && res.data.code != 0) {
            sendVCClickable = true;
        } else {
            sendVCClickable = false;
            Server.showMessage("邮箱已被注册！", 'error')
            throw new Error("邮箱已被注册！")
        }
    });
}
const vcChecked = ref(false)
let sendVC = async () => {
    vcChecked.value = false
    registerData.vc = ''
    registerFormRef.validateField(['email']).then(async () => {
        Server.get("/user/registry/send_email_vc",
            {email: registerData.email}, false).then((res) => {
                if (res.data && res.data.code == 0) {
                    sentVCTimeTick(3)
                    sendVCClickable = true;
                    lastvc = ""
                } else {
                    sendVCClickable = false;
                    setTimeout(() => {sendVCClickable = true}, 3000)
                    Server.showMessage(res.data.message)
                    throw new Error(res.data.message)
                }
            });
    })
}
let lastvc = ""
let checkVC = async () => {
    if (lastvc != registerData.vc)
        registerFormRef.validateField(['email']).then(async () => {
            if (sendVCClickable) {
                lastvc = registerData.vc
                Server.get("/user/registry/check_email_vc", {vc: registerData.vc}, false).then((res) => {
                    console.log(res.data)
                    if (res.data && res.data.code == 0) {
                        vcChecked.value = true
                    } else {
                        vcChecked.value = false
                        Server.showMessage(res.data.message)
                        throw new Error(res.data.message)
                    }
                    sendVCClickable = true;
                    registerFormRef.validateField(['vc'])
                });
            }
        })
}
let sendVCClickable = $ref(false)
let sendVCCTimer = null
const registerRules = reactive<FormRules>({
    username: [
        {required: true, message: "请输入用户名", trigger: "blur"},
        {min: 6, max: 15, message: "长度在6到15", trigger: "blur"},
        {asyncValidator: checkUsername, trigger: "blur"},
    ],
    email: [
        {// when email is validated, send-code button will be clickable.
            validator: (rule: any, value: any, callback: any) => {
                sendVCClickable = false;
                callback()
            }, trigger: ['blur', 'change']
        },
        {required: true, message: "请输入邮箱", trigger: "blur"},
        {type: 'email', message: "请输入正确的邮箱", trigger: ['blur', 'change']},
        {
            asyncValidator: (rule: any, value: any, callback: any) => {
                sendVCClickable = true;
                callback()
            }, trigger: ['blur', 'change']
        },
    ],
    vc: [
        {required: true, message: "请输入验证码", trigger: ['blur', 'change']},
        {min: 6, max: 6, message: "", trigger: ['blur', 'change']},
        {
            asyncValidator: async (rule: any, value: any, callback: any) => {
                await checkVC()
                if (vcChecked.value)
                    callback()
                else
                    callback(new Error(""))
            }, trigger: ['blur', 'change']
        },
    ],
    password: [
        {required: true, message: "请输入密码", trigger: "blur"},
        {min: 6, max: 32, message: "长度在6到32", trigger: "blur"},
    ],
});
Server.get("/user/has_login")
    .then((res) => {
        let data = res.data;
        if (data && data.code == 0) {
            let res = data.return;
            for (let k of Object.keys(res)) {
                (user as any)[k] = res[k]
            }
            if (res.avatar) user.avatar = res.avatar;
        }
    })
    .catch((err) => {
        console.log(err);
    });

const submitLogin = async () => {
    localStorage.setItem('rememberPassword', 0 + (rememberPassword as any) + "")
    if (rememberPassword) {
        localStorage.setItem('username', loginData.username)
        localStorage.setItem('password', loginData.password)
    } else {
        localStorage.removeItem('username')
        localStorage.removeItem('password')
    }
    await Server.post("/user/login", loginData, true)
        .then((res) => {
            // console.log(res)
            let data = res.data;
            if (data && data.code == 0) {
                let res = data.return;
                // console.log(res);
                user.user_name = res.user_name;
                user.uid = res.uid;
                user.name = res.name;
                user.tel = res.tel;
                user.is_admin = res.is_admin;
                user.is_guide = res.is_guide;
                user.avatar = res.avatar;
                loginVisiable = false;
            }
        })
        .catch((err) => {
            console.log(err);
        });
};

const logout = () => {
    user.uid = 0;
    Server.get("/user/logout", {}, true);
};
const submitRegister = async (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    await formEl.validate(async (valid, fields) => {
        if (valid) {
            await Server.post("/user/registry", registerData, true).then((res) => {
                console.log(res);
                if (res.data && res.data.code == 0) {
                    registerVisiable = false;
                }
            });
        } else {
            console.log("error submit!", fields);
        }
    });
};
let loginVisiable = $ref(false);
let registerVisiable = $ref(false);
let route = useRoute()
let gotoSpace = () => {
    let inSpace = route.name == 'space'
    router.push({name: 'space', params: {userid: user.uid}}).then(() => {
        if (inSpace)
            router.go(0)
    })
}

</script>
<template>
    <el-link v-if="user.uid == 0"
        @click="loginVisiable = true" class="login-link">
        登录|注册
    </el-link>
    <span v-else>
        <el-space alignment="center" :size="15">
            <div style="margin-left: 20px">
                <el-avatar class='hp' :size="35"
                    :src="Server.fileBaseURL + user.avatar"
                    @click="gotoSpace" />
            </div>
            <el-popconfirm title="确定要登出吗?"
                @confirm="logout">
                <template #reference>
                    <el-link
                        style="margin-top: -7px; min-width: 45px"
                        class="fontsize1">
                        登出
                    </el-link>
                </template>
            </el-popconfirm>
        </el-space>
    </span>
    <el-dialog title="登录" v-model="loginVisiable"
        width="300px" center>
        <div id="login">
            <div id="login__input">
                <el-input v-model="loginData.username"
                    class="w-50 m-2" placeholder="请输入账号"
                    :prefix-icon="Avatar" />
                <el-input v-model="loginData.password"
                    type="password" class="w-50 m-2"
                    placeholder="请输入密码" :prefix-icon="Lock"
                    @keyup.enter="submitLogin" />
            </div>
            <div style="align-self: flex-start">
                <el-checkbox v-model="rememberPassword">
                    记住密码
                </el-checkbox>
            </div>
            <el-button type="primary" style="width: 100%"
                @click="submitLogin">
                登录
            </el-button>
            <el-link type="primary"
                @click="loginVisiable = false; registerVisiable = true;">
                注册账号
            </el-link>
        </div>
    </el-dialog>
    <el-dialog title="注册" v-model="registerVisiable"
        width="400px" center @close="loginVisiable = true">
        <div id="register">
            <el-form ref="registerFormRef"
                :model="registerData" :rules="registerRules"
                label-width="120px" label-position="top"
                status-icon>
                <el-form-item label="用户名" prop="username">
                    <el-input
                        v-model="registerData.username"
                        autocomplete="off" />
                </el-form-item>
                <el-form-item label="密码" prop="password">
                    <el-input
                        v-model="registerData.password"
                        type="password"
                        autocomplete="off" />
                </el-form-item>
                <el-form-item label="邮箱" prop="email">
                    <el-input v-model="registerData.email"
                        autocomplete="off" />
                </el-form-item>
                <el-form-item label="验证码" prop="vc">
                    <div class="fhs vc-input">
                        <el-input v-model="registerData.vc"
                            autocomplete="off" />
                        <el-button @click="sendVC"
                            type="primary"
                            :disabled="!sendVCClickable || sentVCTime > 0"
                            plain class="b1">
                            {{ sentVCTime > 0
                                    ?
                                    `${sentVCTime}s后重新发送`
                                    :
                                    "发送验证码"
                            }}
                        </el-button>
                    </div>
                </el-form-item>
                <el-button type="primary"
                    style="width: 100%; margin-top: 20px"
                    @click="submitRegister(registerFormRef)">
                    注册
                </el-button>
            </el-form>
        </div>
    </el-dialog>
</template>
<style lang="scss" scoped>
.login-link {
    text-decoration: none;
    border-radius: 2px;
    padding: 15px;
    border-bottom: 2px solid gainsboro;
    font-size: 16px;

    transition: all 0.3s ease;
}

.login-link:hover {
    border-bottom: 2px solid dodgerblue;
}

#login {
    display: flex;
    flex-flow: column nowrap;
    align-items: center;
    justify-content: space-around;
    height: 200px;

    #login__input {
        width: 100%;
        flex-grow: 0.7;
        display: flex;
        justify-content: space-around;
        flex-flow: column nowrap;
    }
}

#register {
    top: 20vh;
    width: 100%;
    z-index: 1000;
    flex-flow: column nowrap;
    align-items: center;

    .vc-input {
        width: 100%;
    }

    .b1 {
        margin-left: 8px;
    }
}

.message-tips {
    display: flex;
    flex-flow: row nowrap;
    background-color: grey;
    position: fixed;
    z-index: 2000;
}
</style>
<style>
.el-dialog {
    /* --el-dialog-width: 60% !important; */
    min-width: 200px;
    max-width: 700px;
}
</style>
